package games

import (
	"bytes"
	"context"
	"fmt"
	"github.com/chromedp/cdproto/page"
	"github.com/chromedp/chromedp"
	"image/jpeg"
	"xmediaEmu/pkg/inpututil"
	"xmediaEmu/pkg/log"

	// "image/png"
	iImage "xmediaEmu/pkg/image"
)

// 只适合文心一言AI.
const timeFPS = 25 // 20 frames per second.

// 目前AI服务已接入文心一言、九天、科大讯飞大模型~九天：http://10.153.90.5:9088/jiutian#/pages/index/index?callid=95271
// 文心：http://10.153.90.5:9088/yiyan#/pages/index/index?callid=95271
// 讯飞：http://10.153.90.5:9088/xunfei#/pages/index/index?callid=95271
// const webAiUrl = "http://10.153.90.5:9088/#/pages/index/index?callid="
// const webAiUrl = "http://10.153.90.5:9088/yiyan#/pages/index/index?callid="
const webAiUrl = "http://10.153.90.5:9088/jiutian#/pages/index/index?callid="

type GameChromeDp struct {
	roomId string
	width  int
	height int

	chromeContext context.Context
	cancel        context.CancelFunc

	fpsCounter int
	// finished bool

	// input.
	askText string

	isRunning bool
}

func NewGameChromeDp(roomId string) *GameChromeDp {
	//

	// 文心一言.
	url := webAiUrl + roomId
	instance := chromeDpList.PopFront()
	var game *GameChromeDp
	if instance == nil {
		game = &GameChromeDp{width: screenWidth, height: screenHeight, roomId: roomId, isRunning: true}
		ctx, _ := chromedp.NewExecAllocator(
			context.Background(),

			// 以默认配置的数组为基础，覆写headless参数
			// 当然也可以根据自己的需要进行修改，这个flag是浏览器的设置
			append(
				chromedp.DefaultExecAllocatorOptions[:],
				chromedp.NoSandbox,
				chromedp.DisableGPU,
				chromedp.NoFirstRun,
				chromedp.NoDefaultBrowserCheck,
				//禁用网络安全标志
				chromedp.Flag("disable-web-security", true),
				//关闭插件支持
				chromedp.Flag("disable-extensions", true),
				//关闭默认浏览器检查
				chromedp.Flag("disable-default-apps", true),
				chromedp.WindowSize(game.width, game.height),
			)...,
		)

		game.chromeContext, game.cancel = chromedp.NewContext(
			ctx,
			// chromedp.WithDebugf(log.Printf),
		)

		if err := chromedp.Run(game.chromeContext,
			chromedp.Navigate(url),
			chromedp.WaitVisible(`#inputEle`)); err != nil {
			panic(err)
		}

		log.Logger.Info("NewGameChromeDp new started.")
	} else {
		game = instance.(*GameChromeDp)
		game.isRunning = true
		game.roomId = roomId

		if err := chromedp.Run(game.chromeContext,
			chromedp.Navigate(url),
			chromedp.WaitVisible(`#inputEle`)); err != nil {
			panic(err)
		}
		err := chromedp.Run(game.chromeContext, chromedp.Evaluate(`location.reload();`, nil))
		if err != nil {
			fmt.Println(err)
		}
		log.Logger.Info("NewGameChromeDp chromeDpList.PopFront started.")
	}
	//ctx, _ := chromedp.NewExecAllocator(
	//	context.Background(),
	//
	//	// 以默认配置的数组为基础，覆写headless参数
	//	// 当然也可以根据自己的需要进行修改，这个flag是浏览器的设置
	//	append(
	//		chromedp.DefaultExecAllocatorOptions[:],
	//		chromedp.WindowSize(game.width, game.height),
	//	)...,
	//)
	//
	//game.chromeContext, game.cancel = chromedp.NewContext(
	//	ctx,
	//	// chromedp.WithDebugf(log.Printf),
	//)

	// 带room id访问:
	//if err := chromedp.Run(game.chromeContext, chromedp.Navigate(`https://lab.hakim.se/particles/02/`)); err != nil {
	//	panic(err)
	//}
	// chromedp.EmulateViewport(1920, 2000),  //adjust size and scale, 使用EmulateViewportOption.
	//if err := chromedp.Run(game.chromeContext,
	//	chromedp.Navigate(`http://htmlpreview.github.io/?https://github.com/Syske/printer/blob/master/textPrinter.html`)); err != nil {
	//	panic(err)
	//}

	// End

	//if err := chromedp.Run(game.chromeContext, chromedp.Emulate(device.IPhone7landscape),
	//	chromedp.Navigate(`https://juejin.cn/post/7106018120036253710`)); err != nil {
	//	panic(err)
	//}

	//if err := chromedp.Run(game.chromeContext,
	//	chromedp.Navigate(`https://mbd.baidu.com/newspage/data/landingsuper?context=%7B%22nid%22%3A%22news_9468927497550505071%22%7D&n_type=-1&p_from=-1`)); err != nil {
	//	panic(err)
	//}
	log.Logger.Info("GameChromeDp started, roomId:", game.roomId)
	return game
}

func (g *GameChromeDp) Layout(outsideWidth, outsideHeight int) (int, int) {
	// return screenWidth, screenHeight
	return g.width, g.height
}

// Update 更新输入text和key.
// Update在Draw前面.
func (g *GameChromeDp) Update(text string, key inpututil.Key) error {
	if !g.isRunning {
		return nil
	}
	// TODO: 滚动网页.
	// 调试输入事件.
	if text != "" {
		g.askText = text
		log.Logger.Debugf("GameChromeDp Update text:%s, key:%d.", text, key)

		if g.askText == "1" {
			// err := chromedp.Run(g.chromeContext, chromedp.KeyEvent(kb.ArrowUp))
			err := chromedp.Run(g.chromeContext, chromedp.Evaluate(`document.getElementById('pageUp').click();`, nil))
			if err != nil {
				log.Logger.Errorf("GameChromeDp pageUp failed text:%s, err:%v.", text, err)
			}

			return nil
		} else if g.askText == "2" {
			err := chromedp.Run(g.chromeContext, chromedp.Evaluate(`document.getElementById('pageDown').click();`, nil))
			// err := chromedp.Run(g.chromeContext, chromedp.KeyEvent(kb.ArrowDown))
			if err != nil {
				log.Logger.Errorf("GameChromeDp pageDown failed text:%s, err:%v.", text, err)
			}
			return nil
		}

		// 直接在此处
		err := chromedp.Run(g.chromeContext, chromedp.SetJavascriptAttribute(`#inputEle`, "innerHTML", text, chromedp.ByID), chromedp.Evaluate(`document.getElementById('sendMsg').click();`, nil))
		if err != nil {
			log.Logger.Errorf("GameChromeDp Update failed text:%s, err:%v.", text, err)
		}
	}
	return nil
}

// Draw 输出到本地检验是否成功.
func (g *GameChromeDp) Draw(dc *iImage.Context) {
	if !g.isRunning {
		return
	}

	// 测试性能打开: 打开性能更差.
	// dc.Clear()

	// 离屏渲染.
	var buf []byte
	// navigate
	//if g.isInit == false {
	//	if err := chromedp.Run(g.chromeContext, chromedp.Navigate(`https://lab.hakim.se/particles/02/`)); err != nil {
	//		panic(err)
	//	}
	//	g.isInit = true
	//}
	// 页面截图.
	if err := chromedp.Run(g.chromeContext, HighQualityScreenShot(50, &buf)); err != nil {
		panic(err)
	}

	// capture entire browser viewport, returning png with quality=90
	//if err := chromedp.Run(g.chromeContext, fullScreenshot(`https://brank.as/`, 90, &buf)); err != nil {
	//	panic(err)
	//}
	reader := bytes.NewReader(buf)
	img, err := jpeg.Decode(reader)
	if err != nil {
		panic(err)
	}

	dc.DrawImage(img, 0, 0)
}

func (g *GameChromeDp) Stop() {
	log.Logger.Infof("GameChromeDp stopped:%v", g.isRunning)

	// 防止一个协程里调用多次.
	if !g.isRunning {
		return
	}
	g.isRunning = false

	// pterm.FgLightGreen.Println("GameChromeDp stopped.")

	// 重复利用不回收.
	// g.cancel()
	err := chromedp.Run(g.chromeContext, chromedp.Evaluate(`document.getElementById('closeSession').click();`, nil))
	if err != nil {
		log.Logger.Errorf("GameChromeDp document.getElementById('closeSession').click() failed id:closeSession, err:%v.", err)
	}
	chromeDpList.PushBack(g)
}

// HighQualityScreenShot fullScreenshot takes a screenshot of the entire browser viewport.
// Note: chromedp.FullScreenshot overrides the device's emulation settings. Use
// device.Reset to reset the emulation and viewport settings.
//
//	func fullScreenshot(urlstr string, quality int, res *[]byte) chromedp.Tasks {
//		return chromedp.Tasks{
//			chromedp.Navigate(urlstr),
//			chromedp.FullScreenshot(res, quality),
//		}
//	}
func HighQualityScreenShot(quality int, res *[]byte) chromedp.Action {
	return chromedp.ActionFunc(func(ctx context.Context) error {
		var err error
		format := page.CaptureScreenshotFormatPng
		if quality != 100 {
			format = page.CaptureScreenshotFormatJpeg
		}

		*res, err = page.CaptureScreenshot().
			// WithCaptureBeyondViewport(true).
			WithFormat(format).
			WithQuality(int64(quality)).
			Do(ctx)
		return err
	})
}
